package com.neu.flashmall.product.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.neu.flashmall.product.entity.*;
import com.neu.flashmall.product.feign.ThirdPartyFeignService;
import com.neu.flashmall.product.mapper.*;
import com.neu.flashmall.product.service.PmsProductAttrValueService;
import com.neu.flashmall.product.service.PmsSkuInfoService;
import com.neu.flashmall.product.service.PmsSpuImagesService;
import com.neu.flashmall.product.service.PmsSpuInfoService;
import com.neu.flashmall.product.vo.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Transactional
@Service
public class PmsSpuInfoServiceImpl implements PmsSpuInfoService {

    @Resource
    private PmsSpuInfoMapper pmsSpuInfoMapper;

    @Resource
    private PmsCategoryMapper pmsCategoryMapper;

    @Resource
    private PmsBrandMapper pmsBrandMapper;

    @Resource
    private PmsCategoryBrandMapper pmsCategoryBrandMapper;

    @Resource
    private ThirdPartyFeignService thirdPartyFeignService;

    @Resource
    private PmsSpuImagesService pmsSpuImagesService;

    @Resource
    private PmsProductAttrValueService pmsProductAttrValueService;

    @Resource
    private PmsProductAttrValueMapper pmsProductAttrValueMapper;

    @Resource
    private PmsSkuInfoMapper pmsSkuInfoMapper;

    @Resource
    private PmsSkuInfoService pmsSkuInfoService;

    @Resource
    private PmsSkuSaleAttrValueMapper pmsSkuSaleAttrValueMapper;

    //品牌名称验证
    private boolean pmsCategoryBrandName(PmsSpuInfo pmsSpuInfo){
        PmsSpuInfo dataSourceSpu = pmsSpuInfoMapper.selectBySpuName(pmsSpuInfo.getSpuName());
        if(dataSourceSpu != null){
            if(dataSourceSpu.getBrandId() == pmsSpuInfo.getBrandId() && dataSourceSpu.getCategoryId() == pmsSpuInfo.getCategoryId())
                //那就说明传来的商品Spu的名称、类别和品牌是完全相同的，这是Spu所不允许的
                return false;
        }
        return true;
    }

    //品牌类别初始化
    private int pmsCategoryBrandInit(PmsSpuInfo record){
        PmsCategoryBrand pmsCB = new PmsCategoryBrand();
        pmsCB.setCategoryId(record.getCategoryId());
        pmsCB.setBrandId(record.getBrandId());
        pmsCB.setCategoryName(pmsCategoryMapper.selectByPrimaryKey(record.getCategoryId()).getName());
        pmsCB.setBrandName(pmsBrandMapper.selectByPrimaryKey(record.getBrandId()).getName());
        pmsCB.setCount(1);
        int category_brand_num = pmsCategoryBrandMapper.insert(pmsCB);
        return category_brand_num;
    }

    //删除或减少品牌类别关联数量
    private String pmsCategoryBrandDeleteOrDecrease(PmsSpuInfo pmsSpuInfo){
        PmsCategoryBrand pmsCategoryBrand = pmsCategoryBrandMapper.selectByCategoryAndBrandId(pmsSpuInfo.getCategoryId(), pmsSpuInfo.getBrandId());
        Integer count = pmsCategoryBrand.getCount();
        if(count-1 == 0){
            if(pmsCategoryBrandMapper.deleteByCategoryAndBrandId(pmsSpuInfo.getCategoryId(),pmsSpuInfo.getBrandId()) <= 0){
                return "类别品牌关联删除失败";
            }
        }else{
            pmsCategoryBrand.setCount(count-1);
            if(pmsCategoryBrandMapper.updateByPrimaryKey(pmsCategoryBrand) <= 0){
                return "类别品牌关联减少失败";
            }
        }
        return "成功";
    }

    @Override
    public PageInfo<PmsSpuInfo> getPaged(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<PmsSpuInfo> list = pmsSpuInfoMapper.selectAll();

        PageInfo<PmsSpuInfo> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    @Override
    public String deleteByPrimaryKey(Long id) {
        PmsSpuInfo pmsSpuInfo = pmsSpuInfoMapper.selectByPrimaryKey(id);
        String mes = pmsCategoryBrandDeleteOrDecrease(pmsSpuInfo);
        if(mes.equals("类别品牌关联删除失败") || mes.equals("类别品牌关联减少失败")){
            return mes;
        }
        int delete_num = pmsSpuInfoMapper.deleteByPrimaryKey(id);
        if(mes.equals("成功") && delete_num > 0){
            List<Long> idList = this.pmsSkuInfoMapper.selectBySpuId(id);
            String result = pmsSkuInfoService.deleteByList(idList);
            if(!result.equals("删除成功")) return result;
            pmsSpuImagesService.getImagesBySpu(id);
            pmsProductAttrValueService.deleteBySpuId(id);
            int code = thirdPartyFeignService.deleteSpuAllImage(String.valueOf(id)).getCode();
            if(code == 2000) return "删除成功";
            return "oss云服务器删除异常";
        }else if(delete_num > 0){
            return "品牌商品关联删除或减少失败";
        }
        return "Spu删除失败/品牌商品删除或减少失败";
    }

    @Override
    public String insert(PmsSpuInfo record) {
        if(record.getCategoryId() == null || record.getBrandId() == null){
            return "请绑定商品品牌和类别";
        }
        if(!pmsCategoryBrandName(record)){
            return "该商品名称已在该品牌的该类别下存在，请修改";
        }
        record.setPublishStatus(0);
        int insert_num = pmsSpuInfoMapper.insert(record);
        int category_brand_num;
        PmsCategoryBrand pmsCategoryBrand = pmsCategoryBrandMapper.selectByCategoryAndBrandId(record.getCategoryId(),record.getBrandId());
        if(pmsCategoryBrand != null){
            int count = pmsCategoryBrand.getCount();
            pmsCategoryBrand.setCount(count+1);
            category_brand_num = pmsCategoryBrandMapper.updateByPrimaryKey(pmsCategoryBrand);
        }else{
            category_brand_num = pmsCategoryBrandInit(record);
        }
        if(insert_num > 0 && category_brand_num > 0) {
            return "添加成功";
        }else if(insert_num > 0){
            return "品牌和商品关联失败";
        }else if(category_brand_num > 0){
            return "Spu添加失败";
        }
        return "Spu添加失败/品牌和商品关联失败";
    }

    @Override
    public PmsSpuInfo selectByPrimaryKey(Long id) {
        return pmsSpuInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public String updateByPrimaryKey(PmsSpuInfo record) {
        if(record.getBrandId() == null || record.getPublishStatus() == null){
            return "请绑定商品品牌和类别";
        }
        int category_brand_num;
        PmsSpuInfo pmsSpuInfo = pmsSpuInfoMapper.selectByPrimaryKey(record.getId());
        if(pmsSpuInfo.getCategoryId() == record.getCategoryId() && pmsSpuInfo.getBrandId() == record.getBrandId()){
            //不用更新category_brand表的信息
            category_brand_num = 1;
        }else{
            //对category_brand表更新
            //减少当前原始count并判断count是否为0，如果为0对当前关联进行删除
            String mes = pmsCategoryBrandDeleteOrDecrease(pmsSpuInfo);
            if(mes.equals("类别品牌关联删除失败") || mes.equals("类别品牌关联减少失败")){
                return mes;
            }
            //对当前关联进行判断是否存在，如果存在count+1,如果不存在那么需要init当前关联
            PmsCategoryBrand pmsCategoryBrand = pmsCategoryBrandMapper.selectByCategoryAndBrandId(record.getCategoryId(),record.getBrandId());
            if(pmsCategoryBrand == null){
                category_brand_num = pmsCategoryBrandInit(record);
            }else{
                Integer count = pmsCategoryBrand.getCount();
                pmsCategoryBrand.setCount(count+1);
                category_brand_num = pmsCategoryBrandMapper.updateByPrimaryKey(pmsCategoryBrand);
            }
        }
        int update_num = pmsSpuInfoMapper.updateByPrimaryKey(record);
        if(category_brand_num >0 && update_num > 0){
            return "修改成功";
        }else if(update_num > 0){
            return "品牌和商品关联修改失败";
        }else if(category_brand_num > 0){
            return "Spu修改失败";
        }
        return "Spu修改失败/品牌和商品关联修改失败";
    }

    @Override
    public String changePublishStatus(long id) {
        PmsSpuInfo pmsSpuInfo = pmsSpuInfoMapper.selectByPrimaryKey(id);
        if(pmsSpuInfo.getPublishStatus() == 1){
            pmsSpuInfo.setPublishStatus(0);
        }else if(pmsSpuInfo.getPublishStatus() == 0){
            pmsSpuInfo.setPublishStatus(1);
        }
        if(pmsSpuInfoMapper.updateByPrimaryKey(pmsSpuInfo) > 0){
            return "上架状态修改成功";
        }
        return "上架状态修改失败";
    }

    @Override
    public PmsSpuInfo getOne(Long id) {
        return pmsSpuInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public RecommendSpuListVo getRecommendSpuListByCategory(Long categoryId) {
        List<PmsCategory> categoryList = pmsCategoryMapper.selectByParentId(categoryId);
        RecommendSpuListVo result = new RecommendSpuListVo();
        result.setAllSpu(new HashMap<>());
        for(PmsCategory item1 : categoryList){
            List<PmsSpuInfo> allPmsSpuInfo = pmsSpuInfoMapper.selectByCategoryId(item1.getId(),5);
            List<RecommendSpuListVo.SpuItem> data = new ArrayList<>();
            for(PmsSpuInfo item : allPmsSpuInfo){
                RecommendSpuListVo.SpuItem one = new RecommendSpuListVo.SpuItem();
                one.setDetail(item);
                PmsSpuImages images = pmsSpuImagesService.getDefaultImageBySpuId(item.getId());
                if(images != null){
                    one.setDefaultImage(images.getImgUrl());
                }
                one.setPrice(pmsSkuInfoService.getPrice(item.getId()));
                data.add(one);
            }
            result.getAllSpu().put(item1.getId(),data);
        }
        return result;
    }

    @Override
    public List<SpuVo> getFilterSpu(FilterCondition condition) {
        Long pageSize = condition.getPageSize();
        Long pageNum = (condition.getPageNum() - 1) * pageSize;
        List<SpuVo> spuList = new ArrayList<>();
        List<PmsSpuInfo> allSpu = new ArrayList<>();
        if(condition.getConditionList() != null){
            List<PmsProductAttrValue> all = pmsProductAttrValueMapper.selectAll();
            Set<Long> idSet = new HashSet<>();
            List<FilterCondition.Condition> allCondition = condition.getConditionList();
            for(FilterCondition.Condition c : allCondition){
                for(PmsProductAttrValue attr : all){
                    if(attr.getAttrId().equals(c.getAttrId()) && attr.getAttrValue().equals(c.getAttrValue())){
                        idSet.add(attr.getSpuId());
                    }
                }
            }
            List<PmsSkuSaleAttrValue> allSaleValue = pmsSkuSaleAttrValueMapper.selectAll();
            List<PmsSkuInfo> allSkuInfo = pmsSkuInfoMapper.getAllData();
            HashMap<Long,Long> skuToSpu = new HashMap<>();
            for(PmsSkuInfo sku : allSkuInfo){
                skuToSpu.put(sku.getId(),sku.getSpuId());
            }
            for(FilterCondition.Condition c : allCondition){
                for(PmsSkuSaleAttrValue attr : allSaleValue){
                    if(attr.getAttrId().equals(c.getAttrId()) && attr.getAttrValue().equals(c.getAttrValue())){
                        idSet.add(skuToSpu.get(attr.getSkuId()));
                    }
                }
            }
            if(condition.getBrandId() == null){
                allSpu = pmsSpuInfoMapper.selectByIdList(condition.getCategoryId(), new ArrayList<>(idSet),pageSize,pageNum);
            }else{
                allSpu = pmsSpuInfoMapper.selectByIdListAndBrand(new ArrayList<>(idSet), condition.getBrandId(), condition.getCategoryId(),pageSize,pageNum);
            }
        }else{
            if(condition.getBrandId() == null){
                return getByCategoryId(condition.getCategoryId(),pageSize,pageNum);
            }else{
                allSpu = this.pmsSpuInfoMapper.selectByBrandId(condition.getBrandId(), condition.getCategoryId(),pageSize,pageNum);
            }
        }
        for(PmsSpuInfo pmsSpuInfo : allSpu){
            SpuVo s = new SpuVo();
            s.setDetail(pmsSpuInfo);
            s.setPrice(this.pmsSkuInfoService.getPrice(pmsSpuInfo.getId()));
            PmsSpuImages image = this.pmsSpuImagesService.getDefaultImageBySpuId(pmsSpuInfo.getId());
            if(image != null){
                s.setDefaultImage(image.getImgUrl());
            }
            spuList.add(s);
        }
        return spuList;
    }

    @Override
    public List<SpuVo> getByCategoryId(Long categoryId,Long pageSize,Long pageNum) {
        List<SpuVo> result = new ArrayList<>();
        List<PmsSpuInfo> all = this.pmsSpuInfoMapper.selectByCategoryIdNoLimit(categoryId,pageSize,pageNum);
        for(PmsSpuInfo item : all){
            SpuVo vo = new SpuVo();
            vo.setDetail(item);
            vo.setPrice(this.pmsSkuInfoService.getPrice(item.getId()));
            PmsSpuImages pmsSpuImages = this.pmsSpuImagesService.getDefaultImageBySpuId(item.getId());
            if(pmsSpuImages != null){
                vo.setDefaultImage(pmsSpuImages.getImgUrl());
            }
            result.add(vo);
        }
        return result;
    }

    @Override
    public  FatherGoodVo getFatherGoodVo(Long id){
        FatherGoodVo result = new FatherGoodVo();
        PmsSpuInfo spu = this.pmsSpuInfoMapper.selectByPrimaryKey(id);
        result.setId(id);
        result.setName(spu.getSpuName());
        result.setDesc(spu.getSpuDescription());

        PmsCategory third = this.pmsCategoryMapper.selectByPrimaryKey(spu.getCategoryId());
        PmsCategory second = this.pmsCategoryMapper.selectByPrimaryKey(third.getParentId());
        result.setSecondCategoryName(second.getName());
        result.setSecondCategoryId(second.getId());
        result.setThirdCategoryId(third.getId());
        result.setThirdCategoryName(third.getName());
        List<String> image = new ArrayList<>();
        for(PmsSpuImages one : this.pmsSpuImagesService.getImagesBySpu(id)){
            image.add(one.getImgUrl());
        }
        result.setImageList(image);
        return result;
    }

    @Override
    public List<SpuVo> getByKeyWord(String keyWord) {
        List<SpuVo> spuVoList = new ArrayList<>();
        HashSet<Long> idSet = new HashSet<>();
        List<Long> idList = searchByNameAndDescription(keyWord);
        for(Long id : idList){
            idSet.add(id);
        }
        idList = pmsSkuInfoService.searchByKeyWord(keyWord);
        for(Long id : idList){
            idSet.add(id);
        }
        for(Long id : idSet){
            SpuVo spuVo = new SpuVo();
            PmsSpuInfo info = pmsSpuInfoMapper.selectByPrimaryKey(id);
            spuVo.setDetail(info);
            PmsSpuImages image = pmsSpuImagesService.getDefaultImageBySpuId(id);
            if(image != null){
                spuVo.setDefaultImage(image.getImgUrl());
            }
            spuVo.setPrice(pmsSkuInfoService.getPrice(id));
            spuVoList.add(spuVo);
        }
        return spuVoList;
    }

    private List<Long> searchByNameAndDescription(String keyWord){
        return pmsSpuInfoMapper.searchByKeyWord("%" + keyWord + "%");
    }


}
